#!/bin/bash

# FlowPlan Docker集成测试脚本
# 用于验证Docker容器化环境的完整性

set -e  # 遇到错误立即退出

echo "🐳 FlowPlan Docker集成测试"
echo "================================"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}ℹ️  $1${NC}"
}

log_success() {
    echo -e "${GREEN}✅ $1${NC}"
}

log_warning() {
    echo -e "${YELLOW}⚠️  $1${NC}"
}

log_error() {
    echo -e "${RED}❌ $1${NC}"
}

# 检查Docker是否安装
check_docker() {
    log_info "检查Docker环境..."
    
    if ! command -v docker &> /dev/null; then
        log_error "Docker未安装，请先安装Docker"
        exit 1
    fi
    
    if ! command -v docker-compose &> /dev/null; then
        log_error "Docker Compose未安装，请先安装Docker Compose"
        exit 1
    fi
    
    log_success "Docker环境检查通过"
}

# 清理现有容器
cleanup_containers() {
    log_info "清理现有容器..."
    
    # 停止并删除相关容器
    docker-compose down -v --remove-orphans 2>/dev/null || true
    
    # 清理可能存在的同名容器
    docker rm -f flowplan-db flowplan-backend flowplan-frontend 2>/dev/null || true
    
    log_success "容器清理完成"
}

# 构建和启动服务
start_services() {
    log_info "构建并启动服务..."
    
    # 构建镜像
    log_info "构建Docker镜像..."
    docker-compose build --no-cache
    
    # 启动服务
    log_info "启动所有服务..."
    docker-compose up -d
    
    log_success "服务启动命令执行完成"
}

# 等待服务就绪
wait_for_services() {
    log_info "等待服务启动..."
    
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        log_info "检查服务状态 (${attempt}/${max_attempts})..."
        
        # 检查数据库
        if docker-compose exec -T db pg_isready -U flowplan &>/dev/null; then
            log_success "数据库服务就绪"
            break
        fi
        
        if [ $attempt -eq $max_attempts ]; then
            log_error "服务启动超时，请检查日志"
            docker-compose logs
            return 1
        fi
        
        sleep 10
        ((attempt++))
    done
}

# 检查容器状态
check_container_status() {
    log_info "检查容器运行状态..."
    
    local containers=("flowplan-db" "flowplan-backend")
    local all_running=true
    
    for container in "${containers[@]}"; do
        if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "$container.*Up"; then
            log_success "$container 运行正常"
        else
            log_error "$container 未正常运行"
            all_running=false
        fi
    done
    
    if [ "$all_running" = true ]; then
        log_success "所有核心容器运行正常"
        return 0
    else
        log_error "部分容器运行异常"
        return 1
    fi
}

# 测试数据库连接
test_database() {
    log_info "测试数据库连接..."
    
    if docker-compose exec -T db psql -U flowplan -d flowplan -c "SELECT 1;" &>/dev/null; then
        log_success "数据库连接测试通过"
        
        # 检查表是否存在
        local table_count=$(docker-compose exec -T db psql -U flowplan -d flowplan -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';" | xargs)
        log_info "数据库表数量: $table_count"
        
        if [ "$table_count" -gt 0 ]; then
            log_success "数据库表结构正常"
        else
            log_warning "数据库表为空，可能需要初始化"
        fi
    else
        log_error "数据库连接失败"
        return 1
    fi
}

# 测试后端API
test_backend_api() {
    log_info "测试后端API..."
    
    local backend_url="http://localhost:8080"
    local max_attempts=10
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        log_info "尝试连接后端API (${attempt}/${max_attempts})..."
        
        if curl -f -s "${backend_url}/actuator/health" &>/dev/null; then
            log_success "后端API连接成功"
            
            # 测试健康检查
            local health_status=$(curl -s "${backend_url}/actuator/health" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
            if [ "$health_status" = "UP" ]; then
                log_success "后端服务健康状态正常"
            else
                log_warning "后端服务健康状态: $health_status"
            fi
            
            return 0
        fi
        
        if [ $attempt -eq $max_attempts ]; then
            log_error "后端API连接失败"
            return 1
        fi
        
        sleep 5
        ((attempt++))
    done
}

# 运行API集成测试
run_api_tests() {
    log_info "运行API集成测试..."
    
    if [ -f "scripts/test-api.py" ]; then
        if command -v python3 &> /dev/null; then
            log_info "执行Python API测试脚本..."
            python3 scripts/test-api.py --url "http://localhost:8080" --report
            log_success "API测试完成"
        else
            log_warning "Python3不可用，跳过API测试脚本"
        fi
    else
        log_warning "API测试脚本不存在，跳过"
    fi
}

# 显示服务信息
show_service_info() {
    log_info "服务访问信息："
    echo "================================"
    echo "🗄️  数据库: localhost:5432"
    echo "   用户名: flowplan"
    echo "   密码: flowplan123"
    echo "   数据库: flowplan"
    echo ""
    echo "🚀 后端API: http://localhost:8080"
    echo "   健康检查: http://localhost:8080/actuator/health"
    echo "   API文档: http://localhost:8080/swagger-ui.html"
    echo ""
    echo "📱 前端应用: 需要单独构建运行"
    echo "================================"
}

# 清理函数
cleanup_on_exit() {
    log_info "清理测试环境..."
    # 可以选择保留容器用于调试，或者清理
    # docker-compose down -v
    log_info "测试完成"
}

# 主函数
main() {
    echo "开始时间: $(date)"
    
    # 设置退出时清理
    trap cleanup_on_exit EXIT
    
    # 执行测试步骤
    check_docker
    cleanup_containers
    start_services
    wait_for_services
    check_container_status
    test_database
    test_backend_api
    run_api_tests
    
    echo ""
    log_success "🎉 集成测试完成！"
    show_service_info
    
    echo ""
    log_info "查看容器状态: docker-compose ps"
    log_info "查看日志: docker-compose logs [service-name]"
    log_info "停止服务: docker-compose down"
}

# 参数处理
case "${1:-}" in
    "cleanup")
        cleanup_containers
        log_success "清理完成"
        exit 0
        ;;
    "logs")
        docker-compose logs -f
        exit 0
        ;;
    "stop")
        docker-compose down
        log_success "服务已停止"
        exit 0
        ;;
    "help"|"-h"|"--help")
        echo "用法: $0 [命令]"
        echo ""
        echo "命令:"
        echo "  (无参数)  运行完整集成测试"
        echo "  cleanup   清理Docker容器"
        echo "  logs      查看服务日志"
        echo "  stop      停止所有服务"
        echo "  help      显示此帮助信息"
        exit 0
        ;;
    "")
        main
        ;;
    *)
        log_error "未知命令: $1"
        echo "使用 '$0 help' 查看可用命令"
        exit 1
        ;;
esac